package org.example;

import java.lang.reflect.Field;
import java.util.List;

public class TablePrinter {


    public static <T> void printTable(List<T> objects, int... columnWidths) {//泛型类型，表示可以处理任何类型的对象。
        if (objects == null || objects.isEmpty()) {
            System.out.println("没有数据可打印。");
            return;
        }

        Class<?> clazz = objects.get(0).getClass(); // 获取对象的类
        Field[] fields = clazz.getDeclaredFields(); // 获取类的所有字段

        if (fields.length != columnWidths.length) {
            throw new IllegalArgumentException("列宽参数数量与类字段数量不匹配");
        }

        printDivider(columnWidths); // 打印表格分隔线
        printHeader(fields, columnWidths); // 打印表格头
        printDivider(columnWidths); // 再次打印分隔线

        for (T obj : objects) {
            printRow(obj, fields, columnWidths); // 打印每一行的内容
        }
        printDivider(columnWidths); // 最后打印分隔线
    }


    private static void printDivider(int[] columnWidths) {
        for (int width : columnWidths) {//遍历赋值给width
            System.out.print("+" + "-".repeat(width + 2)); // 根据列宽打印分隔线 repeat用来指定重复的分割线
        }
        System.out.println("+"); // 换行
    }


    private static void printHeader(Field[] fields, int[] columnWidths) {//Field[] fields：方法参数，一个 Field 对象数组，表示表头的各个字段。
        //int[] columnWidths：方法参数，一个整数数组，表示每一列的宽度。
        for (int i = 0; i < fields.length; i++) {
            System.out.printf("| %-" + columnWidths[i] + "s ", fields[i].getName()); // 打印每列的标题
        }//"| %-" + columnWidths[i] + "s "：格式化字符串，其中 % 是占位符，- 表示左对齐，columnWidths[i] 是列宽，s 表示字符串。
        //获取 fields 数组中当前索引 i 处的字段名
        System.out.println("|"); // 换行
    }


    private static <T> void printRow(T obj, Field[] fields, int[] columnWidths) {//T 是泛型类型参数，表示方法可以接受任意类型的对象。
        for (int i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true); // 设置字段可访问
            try {
                Object value = fields[i].get(obj); // 获取字段的值
                String valueStr = value == null ? "null" : value.toString(); // 将值转换为字符串，若值为null，则显示"null"
                System.out.printf("| %-" + columnWidths[i] + "s ", truncate(valueStr, columnWidths[i])); // 打印每列的值，并截断过长的值
            } catch (IllegalAccessException e) {
                e.printStackTrace(); // 捕获并打印异常
            }
        }
        System.out.println("|"); // 换行
    }


    private static String truncate(String text, int maxLength) {
        if (text.length() <= maxLength) {
            return text; // 如果文本长度小于等于最大长度，返回文本本身
        } else {
            return text.substring(0, maxLength - 3) + "..."; // 否则截断文本并添加省略号
        }
    }
    // Field[] 是一个 Field 类型的数组，用于存储反射获取的类的所有字段
    //Object value = field.get(obj);获取字段值
}